//
//  NSObject+KeyValue.m
//  SSL_Runtime_Learn
//
//  Created by SSLong on 2018/2/12.
//  Copyright © 2018年 sunshilong. All rights reserved.
//

#import "NSObject+KeyValue.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation NSObject (KeyValue)
//字典转模型
+(id)objectInitWithDictionary:(NSDictionary*)dic{
    id objc = [[self alloc] init];
    
    for (NSString *key in dic.allKeys) {
        
        id value = dic[key];//取值
        
        //1、判断属性是不是Model，如果是Model递归改方法，如果不是向下
        objc_property_t property = class_getProperty(self, key.UTF8String);//获取模型属性
        unsigned int count = 0;//属性数量
        objc_property_attribute_t *attributeList = property_copyAttributeList(property, &count);
        objc_property_attribute_t att = attributeList[0];//获取属性
        NSString *attString = [NSString stringWithUTF8String:att.value];//转OC字符串
        
        if ([attString isEqualToString:@"@\"Person\""]) {
             value = [self objectInitWithDictionary:value];//递归
        }
        //2、用objc_msgSend调用setter方法，进行赋值
        NSString *methodName = [NSString stringWithFormat:@"set%@%@:",[key substringToIndex:1].uppercaseString,[key substringFromIndex:1]];//例如setName：
        SEL setter= sel_registerName(methodName.UTF8String);
        if ([objc respondsToSelector:setter]) {
            ((void (*) (id,SEL,id)) objc_msgSend) (objc,setter,value);//runtime，发消息方法
        }
        
        free(attributeList);
        
    }
    
    return objc;
}
//模型转字典
- (NSDictionary*)dictionaryWithObject{
    unsigned int count = 0;
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    
    for (int i=0; i<count; i++) {
        objc_property_t property = propertyList[i];
        
        //getter方法
        const char *propertyName = property_getName(property);
        SEL getter = sel_registerName(propertyName);
        
        if ([self respondsToSelector:getter]) {
            id value = ((id (*) (id,SEL)) objc_msgSend)(self,getter);//获取值
            //判断value是不是Model，如果是，继续递归转化为字典
            if ([value isKindOfClass:[self class]] && value) {
                value = [value dictionaryWithObject];
            }
            //不是Model，继续转化
            if (value) {
                NSString *key = [NSString stringWithUTF8String:propertyName];
                [dic setObject:value forKey:key];
            }
        }
    }
    free(propertyList);
    
    return dic;
}
@end
